package com.ibm.cps.servlet;

import java.io.PrintWriter;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.fasterxml.jackson.databind.node.ArrayNode;
import com.fasterxml.jackson.databind.node.ObjectNode;
import com.google.common.base.Throwables;
import com.ibm.cps.forwarder.MessageForwarder;
import com.ibm.cps.message.MessageFields;
import com.ibm.cps.model.ServletUtil;
import com.ibm.cps.servlet.starter.WorkerProcessManager;
import com.ibm.interfaces.IPersistency;
import com.ibm.mongo.MongoPersistency;
import com.ibm.util.ErrorCode;
import com.ibm.util.JSONUtility;
import com.ibm.util.LocalConfig;
import com.ibm.util.exception.CPSException;

public class Service extends HttpServlet {

	private static Logger logger = LoggerFactory.getLogger(Service.class);
	private static final long serialVersionUID = 1L;
	private IPersistency persist = null;
	private static WorkerProcessManager messageForwarderManager;
	private static WorkerProcessManager topologyManager;

	@Override
	public void init() throws ServletException {
		try {
			persist = MongoPersistency.getInstace();
			messageForwarderManager = WorkerProcessManager.createManagerForMessageForwarder();
			TopologyMode topologyMode = TopologyMode.valueOf(LocalConfig.CPS_MODE);
			logger.info("Current topology mode: " + topologyMode);
			topologyManager = WorkerProcessManager.createWorkerProcessManager(topologyMode);
		} catch (Exception e) {
			logger.error(Throwables.getStackTraceAsString(e));
		}
	}

	@Override
	protected void doGet(HttpServletRequest req, HttpServletResponse resp) {
		/**
		 * argument: tenantid
		 */
		String tenantid = req.getParameter(MessageFields.TENANTID);
		PrintWriter writer = null;
		String retMsg = null;
		try {
			writer = resp.getWriter();
			if (tenantid == null) {
				throw new CPSException(ErrorCode.NULL_FIELD_ERROR,
						"Please provide tenant id.");
			} else {
				String server = persist.getTenantStatus(tenantid);
				retMsg = ServletUtil.constructReturnMsg(ErrorCode.SUCCESS_CODE,
						server);
			}
		} catch (Throwable e) {
			retMsg = e.getMessage();
		} finally {
			writer.write(retMsg);
			writer.close();
		}
	}

	/**
	 * Set the messaging server credentials and start/stop the service
	 */
	@Override
	protected void doPut(HttpServletRequest req, HttpServletResponse resp) {
		/**
		 * arguments: tenantid serverIp port type
		 */
		String retMsg = null;
		PrintWriter writer = null;
		try {
			writer = resp.getWriter();
			String tenantId = req.getParameter(MessageFields.TENANTID);
			if (tenantId == null) {
				throw new CPSException(ErrorCode.NULL_FIELD_ERROR,
						"Please provide tenant id.");
			}
			String input = ServletUtil.getInputArguments(req.getInputStream());
			ArrayNode servers = JSONUtility.getArrayFromString(input);
			for (int i = 0; i < servers.size(); i++) {
				ObjectNode server = (ObjectNode) servers.get(i);
				server.put(MessageFields.TENANTID, tenantId);
				if (!server.has(MessageFields.STATUS)) {
					throw new CPSException(ErrorCode.INVALID_INPUT_ERROR,
							"Please provide the value of status.");
				}

				String status = JSONUtility.GetString(MessageFields.STATUS,
						server);
				persist.putTenantStatus(tenantId, status);
				if (status.equals("start")) {
					
					logger.info("received start request for tenant: " + tenantId);
					messageForwarderManager.start(tenantId);
					topologyManager.start(tenantId);
					retMsg = ServletUtil.constructReturnMsg(
							ErrorCode.SUCCESS_CODE,
							"Successfully started process topology.");
				} else if (status.equals("stop")) {
					messageForwarderManager.stop(tenantId);
					topologyManager.stop(tenantId);
					retMsg = ServletUtil.constructReturnMsg(
							ErrorCode.SUCCESS_CODE,
							"Successfully stopped process topology.");
				} else {
					throw new CPSException(ErrorCode.INVALID_REQUEST_CODE,
							"Error server status " + status + " in "
									+ server.toString());
				}
			}
		} catch (Throwable e) {
			if (e instanceof CPSException) {
				retMsg = e.getMessage();
			} else {
				retMsg = Throwables.getStackTraceAsString(e);
				retMsg = ServletUtil.constructReturnMsg(
						ErrorCode.INTERNAL_ERROR_CODE, retMsg);
			}
			logger.error(retMsg);
		} finally {
			writer.write(retMsg);
			writer.close();
		}
	}

	public static void main(String[] args) {
		String classpath = MessageForwarder.class.getProtectionDomain()
				.getCodeSource().getLocation().toString();
		String parent = classpath.substring(0, classpath.lastIndexOf("/") + 1)
				+ "*";
		System.out.println(parent + "*");
	}
}
